#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <string.h>
#include <functional>
namespace ThreadModule
{
    static int numb = 1;
    class Thread
    {
        typedef std::function<void *()> func_t;

    private:
        static void *Routine(void *args)
        {
            Thread *self = static_cast<Thread *>(args);
            if (self->_joinable == false)
            {
                self->EnableDetach();
                self->Detach();
            }
            if (self->_isrunning == true)
                return nullptr;
            self->_func();
            return nullptr;
        }

    public:
        Thread(func_t func)
            : _tid(0), _isrunning(false), _joinable(true), _func(func)
        {
            _name = "thread  -" + std::to_string(numb++);
        }
        void EnableDetach()
        {
            if (_joinable == true)
                return;
            _joinable = false;
            return;
        }

        void EnableRunning()
        {
            if (_isrunning == true)
                return;
            _isrunning = true;
            return;
        }

        void Detach()
        {
            EnableDetach();
            pthread_detach(_tid);
        }

        bool Start()
        {
            if (_isrunning == true)
            {
                return false;
            }
            int result = pthread_create(&_tid, nullptr, Routine, this);
            if (result != 0)
            {
                std::cerr << "create thread failed" << strerror(result) << std::endl;
                return false;
            }
            else
            {
                std::cout << "create thread success" << std::endl;
            }
            return true;
        }

        bool Stop()
        {
            if(_isrunning == false)
            {
                return false;
            }
            int result = pthread_cancel(_tid);
            if(result != 0)
            {
                std::cerr << _name << "stop failed:" << strerror(result) <<std::endl;
                return false;
            }
            else
            {
                std::cout << _name <<"stop successed" << std::endl;
            }
            return true;
        }

        bool Join()
        {
            if(_joinable == false)
            {
                std::cout <<"新线程已经分离无法join" << std::endl;
                return false;
            }

            int result = pthread_join(_tid , &_ret);

            if(result != 0)
            {
                std::cerr << "join failed :" << strerror(result) << std::endl;
            }
            else
            {
                std::cout << _name << "已经被分离" <<std::endl; 
                return true;
            }
            return true;
        }

        ~Thread()
        {
        }

    private:
        func_t _func;
        pthread_t _tid;
        std::string _name;
        bool _joinable;
        bool _isrunning;
        void* _ret;
    };
}